package com.hy;

import java.util.Arrays;

/**
 * Created With IntelliJ IDEA.
 * Descriptions:递增的三元子序列
 *
 * 给你一个整数数组 nums ，判断这个数组中是否存在长度为 3 的递增子序列。
 * 如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ，使得 nums[i] < nums[j] < nums[k] ，返回 true ；否则，返回 false 。
 *
 * 示例 1：
 * 输入：nums = [1,2,3,4,5]
 * 输出：true
 * 解释：任何 i < j < k 的三元组都满足题意
 *
 * 示例 2：
 * 输入：nums = [5,4,3,2,1]
 * 输出：false
 * 解释：不存在满足题意的三元组
 *
 * 示例 3：
 * 输入：nums = [2,1,5,0,4,6]
 * 输出：true
 * 解释：三元组 (3, 4, 5) 满足题意，因为 nums[3] == 0 < nums[4] == 4 < nums[5] == 6
 *
 * 提示：
 * 1 <= nums.length <= 5 * 10^5
 * -2^31 <= nums[i] <= 2^31 - 1
 *
 * User:Mr.Du
 * Date:2024/3/23
 * Time:15:22
 */
public class IncreasingTriplet {

    /**
     * 最长递增子序列的变形，不过超时
     * @param nums
     * @return
     */
    public boolean increasingTriplet1(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n];
        Arrays.fill(dp, 1);
        dp[0] = 1;
        for(int i = 1;i < n;i++){
            for(int j = 0;j < i;j++){
                if(nums[i] > nums[j]){
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                    if(dp[i] >= 3) return true;
                }
            }
        }
        return false;
    }

    /**
     *
     * @param nums
     * @return
     */
    public boolean increasingTriplet2(int[] nums){
        int n = nums.length;
        // 记录从左到右的最小值，以i结尾的
        int[] left = new int[n];
        left[0] = nums[0];
        for(int i = 1;i < n;i++){
            left[i] = Math.min(left[i - 1], nums[i]);
        }
        // 记录从右向左的最大值，以i结尾的
        int[] right = new int[n];
        right[n-1] = nums[n-1];
        for(int i = n - 2;i >= 0;i--){
            right[i] = Math.max(right[i+1], nums[i]);
        }
        for(int i = 1;i < n - 1;i++){
            if(nums[i] > left[i-1] && nums[i] < right[i+1]) return true;
        }
        return false;

    }


    public boolean increasingTriplet(int[] nums) {
        int x = Integer.MAX_VALUE, y = x;
        for(int i : nums){
            if(i <= x) x = i;
            else if(i <= y) y = i;
            else return true;
        }
        return false;
    }
}
